/**
* Copyright (c) By zengqh.
*
* This program is just for fun or demo, in the hope that it  
* will be useful, you can redistribute it and/or modify freely.
*
* Time: 2013/05/29
* File: enn_timer.h
* Blog: http://www.cnblogs.com/zengqh/
**/

#pragma once

#include "enn_platform_headers.h"

namespace enn
{

/// Low-resolution operating system timer.
class Timer : public Noncopyable, public AllocatedObject
{
public:
	/// Construct. Get the starting clock value.
	Timer();

	/// Return elapsed milliseconds and optionally reset.
	unsigned GetMSec(bool reset);
	/// Reset the timer.
	void Reset();

private:
	/// Starting clock value in milliseconds.
	unsigned startTime_;
};

class Time : public Noncopyable, public AllocatedObject
{
public:
	/// Construct.
	Time();
	/// Destruct. Reset the low-resolution timer period if set.
	virtual ~Time();

	/// Begin new frame, with (last) frame duration in seconds and send frame start event.
	void BeginFrame(float timeStep);
	/// End frame. Increment total time and send frame end event.
	void EndFrame();
	/// Set the low-resolution timer period in milliseconds. 0 resets to the default period.
	void SetTimerPeriod(unsigned mSec);

	/// Return frame number, starting from 1 once BeginFrame() is called for the first time.
	unsigned GetFrameNumber() const { return frameNumber_; }
	/// Return current frame timestep as seconds.
	float GetTimeStep() const { return timeStep_; }
	/// Return current low-resolution timer period in milliseconds.
	unsigned GetTimerPeriod() const { return timerPeriod_; }
	/// Return elapsed time from program start as seconds.
	float GetElapsedTime();

	/// Get system time as milliseconds.
	static unsigned GetSystemTime();
	/// Get a date/time stamp as a string.
	static String GetTimeStamp();
	/// Sleep for a number of milliseconds.
	static void Sleep(unsigned mSec);

private:
	/// Elapsed time since program start.
	Timer elapsedTime_;
	/// Frame number.
	unsigned frameNumber_;
	/// Timestep in seconds.
	float timeStep_;
	/// Low-resolution timer period.
	unsigned timerPeriod_;
};

}